package online.shenjian.redis.seckill.service.impl;

import lombok.extern.slf4j.Slf4j;
import online.shenjian.redis.seckill.service.SecKillService;
import org.redisson.api.*;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * @author shenjian
 * @since 2022/11/12
 */
@Service
@Slf4j
public class SecKillServiceImpl implements SecKillService {

    private RedissonClient redissonClient;
    // redis中库中信息
    private static final String PRODUCT_STOCK_KEY = "sk_10001_stock";
    // redis中该商品秒杀到的用户列表
    private static final String PRODUCT_USER_KEY = "sk_10001_user";

    public SecKillServiceImpl(RedissonClient redissonClient) {
        this.redissonClient = redissonClient;
    }

    @Override
    public String doSecKill(String userId, String productId) {
        RKeys rKeys = redissonClient.getKeys();
        if (rKeys.countExists(PRODUCT_STOCK_KEY) == 0) {
            return "秒杀未开始";
        }
        RLock rLock = redissonClient.getLock(PRODUCT_STOCK_KEY + "_lock");
        try {
            boolean locked = rLock.tryLock(30, 60, TimeUnit.SECONDS);
            if (locked) {
                RAtomicLong productStock = redissonClient.getAtomicLong(PRODUCT_STOCK_KEY);
                RSet<String> productUserSet = redissonClient.getSet(PRODUCT_USER_KEY);
                if (productUserSet != null && productUserSet.contains(userId)) {
                    return "您已秒杀过，请勿重复秒杀";
                }
                if (productStock.get() <= 0) {
                    return "很遗憾，秒杀已结束";
                }
                // 加入到秒杀集合
                productUserSet.add(userId);
                // 库存减1
                productStock.decrementAndGet();
                return "恭喜您，秒杀成功！";
            }
        } catch (InterruptedException e) {
            log.error("异常:{}", e.getMessage());
        } finally {
            rLock.unlock();
        }
        return "服务器繁忙";
    }
}
